package com.fleapx.aop;

import com.fleapx.config.DataSourceContextHolder;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * 在dao层决定数据源(注：如果用这方式，service层不能使用事务，否则出问题，因为打开事务打开时，就会觉得数据库源了）
 *
 */
@Aspect
@EnableAspectJAutoProxy(proxyTargetClass = true)
@Component
@Order(1)
public class DataSourceAopInDao {

    private static Logger log = LoggerFactory.getLogger(DataSourceAopInDao.class);

    /**
     * 只读：
     * 不是WriteDataSource注解的对象或方法  && select开头的方法  ||  get开头的方法
     */
    @Pointcut("!@annotation(com.fleapx.aop.WriteDataSource) " +
            "&& (execution(* com.fleapx.mapper..*.select*(..)) " +
            "|| execution(* com.fleapx.mapper..*.get*(..))" +
            "|| execution(* com.fleapx.mapper..*.scan*(..))" +
            "|| execution(* com.fleapx.mapper..*.query*(..)))")
    public void readPointcut() {

    }

    /**
     * 写：
     * WriteDataSource注解的对象或方法 || insert开头的方法  ||  add开头的方法 || update开头的方法
     * || edlt开头的方法 || delete开头的方法 || remove开头的方法
     */
    @Pointcut("@annotation(com.fleapx.aop.WriteDataSource) " +
            "|| execution(* com.fleapx.mapper..*.insert*(..)) " +
            "|| execution(* com.fleapx.mapper..*.add*(..)) " +
            "|| execution(* com.fleapx.mapper..*.update*(..)) " +
            "|| execution(* com.fleapx.mapper..*.edit*(..)) " +
            "|| execution(* com.fleapx.mapper..*.delete*(..)) " +
            "|| execution(* com.fleapx.mapper..*.remove*(..))")
    public void writePointcut() {

    }

    @Before("readPointcut()")
    public void read() {
        DataSourceContextHolder.setRead();
    }

    @Before("writePointcut()")
    public void write() {
        DataSourceContextHolder.setWrite();
    }





/*    @Before("execution(* com.fei.springboot.dao..*.*(..)) "
			+ " and @annotation(com.fei.springboot.annotation.ReadDataSource) ")
	public void setReadDataSourceType() {
		//如果已经开启写事务了，那之后的所有读都从写库读
		if(!DataSourceType.write.getType().equals(DataSourceContextHolder.getReadOrWrite())){
			DataSourceContextHolder.setRead();
		}

	}

	@Before("execution(* com.fei.springboot.dao..*.*(..)) "
			+ " and @annotation(com.fei.springboot.annotation.WriteDataSource) ")
	public void setWriteDataSourceType() {
	    DataSourceContextHolder.setWrite();
	}*/


    @After("readPointcut()")
    public void readAfter(JoinPoint point) {
        //清理掉当前设置的数据源，让默认的数据源不受影响
        System.out.println("读-清空Threadlocal");
        DataSourceContextHolder.clear();
    }

    @After("writePointcut()")
    public void writeAfter(JoinPoint point) {
        //清理掉当前设置的数据源，让默认的数据源不受影响
        System.out.println("写-清空Threadlocal");
        DataSourceContextHolder.clear();
    }
}
